﻿/*
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.Linq;
using System.Reflection;
using Scaffold.Views;
namespace Scaffold
{
    public class ScaffoldController<TElement> : Controller
        where TElement : class, new()
    {
        public ScaffoldController()
        {
        }
        public DataContext DataContext { get; set; }
        public String Name { get { return typeof(TElement).Name; } }
        protected Table<TElement> GetTable()
        {

            var tableType = typeof(Table<TElement>);
            var tableProperty = DataContext.GetType().GetProperties().Where(p => p.PropertyType == tableType).FirstOrDefault();
            if (tableProperty == null)
                throw new Exception(String.Format("The DataContext does not seem to have a table of {0}", typeof(TElement).Name));

            return (Table<TElement>)tableProperty.GetValue(DataContext, null);
        }
        protected TElement GetItem(int id)
        {
            var myType = typeof(TElement);
            var pi = myType.GetProperties().Where(p => (String.Compare(p.Name, "ID", true) == 0 || string.Compare(myType.Name + "ID", p.Name, false) == 0) && p.PropertyType == typeof(Int32)).FirstOrDefault();
            var table = GetTable();
            TElement item = table.Where(t => id == (int)pi.GetValue(t, null)).FirstOrDefault();
            return item;
        }

        public void Index()
        {
            List(0, 30);
        }
        public void List(int pageIndex, int pageSize)
        {

            Table<TElement> table = GetTable();
            ListViewData<TElement> viewData = new ListViewData<TElement>();
            viewData.PageIndex = pageIndex;
            viewData.PageSize = pageSize;
            viewData.Items = (from t in table select t).Skip(viewData.FirstItem).Take(viewData.PageSize);
            RenderView("List", viewData);
        }
        public void View(int id)
        {
            TElement item = GetItem(id);
            RenderView("View", item);

        }
        public void Edit(int id)
        {
            TElement item = GetItem(id);
            RenderView("Edit", item);

        }
        public void Update(int id)
        {
            TElement item = GetItem(id);
            BindingHelperExtensions.UpdateFrom(item, Request.Form);
            DataContext.SubmitChanges();
            RedirectToAction("Index");
        }
        public void Delete(int id)
        {
            TElement item = GetItem(id);
            Table<TElement> table = GetTable();
            table.DeleteOnSubmit(item);
            DataContext.SubmitChanges();
            RedirectToAction("Index");

        }
        public void Create()
        {
            TElement item = new TElement();
            BindingHelperExtensions.UpdateFrom(item, Request.Form);
            Table<TElement> table = GetTable();
            table.InsertOnSubmit(item);
            DataContext.SubmitChanges();
            RedirectToAction("Index");

        }


        public IDictionary<string, Type> Views { get; set; }
    }
}
